package valuecomusa.fijibus.eticket.shorthaul;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.*;
import android.graphics.Color;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.*;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.*;
import valuecomusa.fijibus.eticket.*;
import valuecomusa.fijibus.eticket.db.shorthaul.BusinessDBHandler;
import valuecomusa.fijibus.eticket.service.shorthaul.DataSyncService;
import valuecomusa.fijibus.eticket.service.shorthaul.GpsTrackingService;
import valuecomusa.fijibus.eticket.ws.ConductorValue;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

public class SunBeamStartUp extends Activity
{
    private static int counter = 1;
    private String TAG = "Login";
    private BusinessDBHandler db;
    private Context myContext;
    private Handler theHandler;

    public SunBeamStartUp()
    {
        TAG = TAG + "." + counter++;
        if (counter > 1000000)
            counter = 1;
        theHandler = new Handler();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        //---
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        //---
        WorkingSession.getInstance().setSAMReaderEventListener(samReaderEventListener, false);
        //---------------------------------------------
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0)
        {
            Log.d(TAG, "Return to paused activity");
            finish();
            return;
        }
        if (WorkingSession.getInstance().loggedInConductor != null &&
                WorkingSession.getInstance().currentActivity != null)
        {
            Log.d(TAG, "Bring to front: " + WorkingSession.getInstance().currentActivity.getClass().toString());
            Intent next = new Intent(SunBeamStartUp.this, WorkingSession.getInstance().currentActivity.getClass());
            next.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            startActivity(next);
            finish();
            return;
        }
        //--
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectNetwork() // or .detectAll() for all detectable problems
                .penaltyLog().build());
        //---
        Log.d(TAG, "onCreate...");

        try
        {
            getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        //---
        WorkingSession.getInstance().Reset();
        //--
        if (!Utilities.isGPSEnable(this))
            showSettingsAlert();
        //---
        myContext = this;
        db = new BusinessDBHandler(this);
        //---
        TextView title = (TextView) findViewById(R.id.title_text);
        if (title != null)
            title.setTextColor(Color.rgb(238, 238, 0));
        //--
        String x = db.getRuntimeValues("print-receipt");
        if (x == null || x.length() == 0)
            x = "1";
        if (x.equals("1"))
            WorkingSession.getInstance().printReceipt = true;
        else
            WorkingSession.getInstance().printReceipt = false;
        //--
        x = db.getRuntimeValues("transactions-to-restart");
        if (x == null || x.length() == 0)
            x = "200";
        try
        {
            WorkingSession.getInstance().transactionsToRestart = Integer.parseInt(x);
        }
        catch (Exception ex)
        {
            Log.e(TAG, "[SunBeamStartUp] Parse Transactions to restart failed. " + ex.toString());
            WorkingSession.getInstance().transactionsToRestart = 200;
        }
        //--
        SharedPreferences sp = getSharedPreferences(Declarations.ShortHaul_SharedPrefName, Context.MODE_PRIVATE);
        String cacheId = sp.getString("h2oxW32", "");
        if (cacheId.length() > 0)
        {
            EditText et = (EditText) findViewById(R.id.lgUserName);
            et.setText(cacheId);

            CheckBox remember = (CheckBox) findViewById(R.id.login_chk_remember_id);
            remember.setChecked(true);
        }
        String cachePrinterAddress = sp.getString("PrinterAddress", "");
        if (cachePrinterAddress.length() > 0)
            WorkingSession.getInstance().wifiPrinterAddress = cachePrinterAddress;

        Button signIn = (Button) findViewById(R.id.btSignIn);
        signIn.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                SharedPreferences sp = getSharedPreferences(Declarations.ShortHaul_SharedPrefName, Context.MODE_PRIVATE);
                int loaded = sp.getInt("loaded", 0);

                if (loaded == 0)
                {
                    WorkingSession.getInstance().ShowErrorDialog(
                            SunBeamStartUp.this,
                            "Error",
                            "Application Data not available.\nPlease contact your administrator");

                    return;
                }

                EditText tmp = (EditText) findViewById(R.id.lgUserName);
                String username = tmp.getText().toString();
                tmp = (EditText) findViewById(R.id.lgPassword);
                String password = tmp.getText().toString();

                if (username.length() == 0 || password.length() == 0)
                {
                    WorkingSession.getInstance().ShowErrorDialog(
                            SunBeamStartUp.this,
                            "Sign-In Error",
                            "Please enter username and password.");

                    return;
                }

                String encryptPwd = Encryptor.MD5(password);
                ConductorValue cdt = db.conductorLogin(username, encryptPwd);
                if (cdt == null)
                {
                    WorkingSession.getInstance().ShowErrorDialog(
                            SunBeamStartUp.this,
                            "Sign-In Error",
                            "Invalid username or incorrect password.");
                }
                else
                {
                    WorkingSession.getInstance().loggedInConductor = cdt;

                    CheckBox remember = (CheckBox) findViewById(R.id.login_chk_remember_id);
                    if (remember.isChecked())
                    {
                        SharedPreferences.Editor spe = sp.edit();
                        spe.putString("h2oxW32", cdt.UserName);
                        spe.commit();
                    }

                    Intent next = new Intent(SunBeamStartUp.this, SetupJournal.class);
                    startActivity(next);
                    finish();
                }
            }
        });
        //--
        String bmfSam = sp.getString("BMF-Sam-Slot", "1");
        WorkingSession.getInstance().setSAMBmfSlot(Integer.parseInt(bmfSam));
        String vodaSam = sp.getString("Voda-Sam-Slot", "3");
        WorkingSession.getInstance().setSAMVodaSlot(Integer.parseInt(vodaSam));
        String digicelSam = sp.getString("Digicel-Sam-Slot", "2");
        WorkingSession.getInstance().setSAMVodaSlot(Integer.parseInt(digicelSam));
        //---
        //trying to open card reader
        WorkingSession.getInstance().OpenSAMCardReader();
        //--check usb attached
        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);

        HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
        if (deviceList.isEmpty())
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    this,
                    "Warning",
                    "Please connect the card reader",
                    new DialogInterface.OnClickListener()
                    {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i)
                        {
                            theHandler.post(doCheckDownloadData);
                        }
                    }
            );
        }
        else
            theHandler.post(doCheckDownloadData);

    }

    private Runnable doCheckDownloadData = new Runnable()
    {
        @Override
        public void run()
        {
            if (!CheckDownloadFullData())
            {
                finish();
            }
        }
    };

    @Override
    protected void onStart()
    {

        super.onStart();

        Log.i(TAG, "onStart...");

        //---Start data sync service
        checkMyServiceRunning();
        if (!isSyncServiceRunning)
        {
            Intent intent = new Intent(this, DataSyncService.class);
            startService(intent);
        }
        if (!isGpsTrackingServiceRunning)
        {
            Intent intent = new Intent(this, GpsTrackingService.class);
            startService(intent);
        }
        //---
        if (WorkingSession.getInstance().LoadSavedSession(SunBeamStartUp.this) == true)
        {
            WorkingSession.getInstance().ClearSavedSession(SunBeamStartUp.this);
            WorkingSession.getInstance().CancelShowingToast();
            //--
            Intent next = new Intent(SunBeamStartUp.this, Main.class);
            next.putExtra("INPUT_DIRECT_CHECK_IN", 1);
            startActivity(next);
            finish();
        }
    }

    @Override
    protected void onDestroy()
    {
        Log.d(TAG, "[onDestroy]...");
        super.onDestroy();
    }

    private ProgressDialog progressDialog = null;
    private UIThreadHandler uiThreadHandler = null;

    private boolean CheckDownloadFullData()
    {
        SharedPreferences sp = getSharedPreferences(Declarations.ShortHaul_SharedPrefName, Context.MODE_PRIVATE);
        int loaded = sp.getInt("loaded", 0);
        if (loaded != 0) //already loaded data
            return true;

        progressDialog = new ProgressDialog(this);
        progressDialog.setIndeterminate(false);
        progressDialog.setMessage("Download application data...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);
        progressDialog.show();

        HandlerThread uiThread = new HandlerThread("UIThreadHandler");//to prepare a looper
        uiThread.start();
        uiThreadHandler = new UIThreadHandler(uiThread.getLooper()); //to process UI such as AlertDialog,...
        Thread worker = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                DataCenter dataCenter = new DataCenter(myContext);
                //---
                int total = dataCenter.getTotalDataCount();
                if (total <= 0)
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                //---
                progressDialog.setMax(total);
                //--
                int progressCount = 0;
                int x = 0;
                //--- 1
                x = dataCenter.GetConductorData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 2
                x = dataCenter.GetMemberData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 3
                x = dataCenter.GetBusData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 4
                x = dataCenter.GetRouteData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 5
                x = dataCenter.GetRouteAssignData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 6
                x = dataCenter.GetStageData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 7
                x = dataCenter.GetBusStationData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 8
                x = dataCenter.GetBusStopData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 9
                x = dataCenter.GetExpressFareData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 10
                x = dataCenter.GetStageFareData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                progressCount = x;
                //--- 11
                x = dataCenter.GetBusSeatData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    //ShowDownloadDataError();
                    return;
                }
                progressCount = x;
                //--- 12
                x = dataCenter.GetBusAssignData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    //ShowDownloadDataError();
                    return;
                }
                progressCount = x;
                //--- 13
                x = dataCenter.GetPassengerTypeData(progressDialog, progressCount, null);
                if (x <= 0)//error
                {
                    progressDialog.dismiss();
                    //---
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    //ShowDownloadDataError();
                    return;
                }
                progressCount = x;
                //--- 14
                //--get //bula.mp3, insufficient-balance.mp3, negative-balance.mp3, tapout.mp3
                boolean success = dataCenter.getRecordingFiles(progressDialog, progressCount);
                if (!success)
                {
                    progressDialog.dismiss();
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }
                //--- 15
                String dc = dataCenter.getDefaultCardNumber();
                if (dc == null || dc.length() == 0)
                {
                    progressDialog.dismiss();
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.SHOW_ERROR_DIALOG);
                    return;
                }

                progressDialog.dismiss();
                //---
                SharedPreferences sp = getSharedPreferences(Declarations.ShortHaul_SharedPrefName, Context.MODE_PRIVATE);
                SharedPreferences.Editor spe = sp.edit();
                spe.putInt("loaded", 1);
                spe.putString("lastupdate", Utilities.DateToString(new Date()));
                spe.commit();
                //--
                db.addOrUpdateRuntimeValues("loaded", "1");
                db.addOrUpdateRuntimeValues("lastupdate",
                        String.valueOf(Calendar.getInstance().getTimeInMillis()));
            }
        });

        worker.start();

        Log.i(TAG, "Back to SunBeamStartUp activity...");

        return true;
    }

    private final class UIThreadHandler extends Handler
    {
        public static final int SHOW_ERROR_DIALOG = 1;

        public UIThreadHandler(Looper lp)
        {
            super(lp);
        }

        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case UIThreadHandler.SHOW_ERROR_DIALOG:
                {
                    ShowDownloadDataError();
                    break;
                }
            }
        }

        private void ShowDownloadDataError()
        {
            AlertDialog.Builder dialog = new AlertDialog.Builder(myContext);

            //--
            dialog.setNegativeButton("OK", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialogInterface, int i)
                {
                    finish();
                }
            });
            dialog.setTitle("Error");
            dialog.setMessage("Could not download application data.\nPlease contact your administrator");

            AlertDialog alert = dialog.create();
            alert.show();
        }

    }

    private boolean isSyncServiceRunning = false;
    private boolean isGpsTrackingServiceRunning = false;

    private void checkMyServiceRunning()
    {
        isSyncServiceRunning = false;
        isGpsTrackingServiceRunning = false;
        //--
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager
                .getRunningServices(Integer.MAX_VALUE))
        {
            if (DataSyncService.class.getName().equals(
                    service.service.getClassName()))
            {
                isSyncServiceRunning = true;
            }
            else if (GpsTrackingService.class.getName().equals(
                    service.service.getClassName()))
            {
                isGpsTrackingServiceRunning = true;
            }
        }

    }

    public void showSettingsAlert()
    {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(SunBeamStartUp.this);

        // Setting Dialog Title
        alertDialog.setTitle("GPS is settings");

        // Setting Dialog Message
        alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

        // On pressing Settings button
        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener()
        {
            public void onClick(DialogInterface dialog, int which)
            {
                Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);
            }
        });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
        {
            public void onClick(DialogInterface dialog, int which)
            {
                dialog.cancel();
            }
        });

        // Showing Alert Message
        alertDialog.show();
    }

    private WorkingSession.SAMReaderEvent samReaderEventListener = new WorkingSession.SAMReaderEvent()
    {
        @Override
        public void OnReaderStateChange(String state)
        {
            Log.d(TAG, "[OnReaderStateChange] " + state);
            WorkingSession.getInstance().ShowToast(SunBeamStartUp.this,
                    "Card Reader " + state,
                    Toast.LENGTH_SHORT);
        }

        @Override
        public void OnSAMSlotStateChange(int slot, String state)
        {

        }

        @Override
        public void OnSmartCardInteraction(com.valuecomusa.Enums.CardProvider cardProvider, int status, String description)
        {

        }
    };
}
